﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.IO;
using Microsoft.Win32;
using System.Security;

namespace GenIX
{

    public partial class RegistrationForm : Form
    {

        //<LOGIN_VARIABLES> Переменные, которые будут хранить на протяжение работы программы логин и пароль </LOGIN_VARIABLES>
        private string login = string.Empty;
        private string password = string.Empty;
        //<USERS_ITEM> Экземпляр класса пользователей.</USER_ITEM>
        private Users user = new Users(); 
        private string SecurityPath = string.Empty;
       

        public RegistrationForm()
        {
            InitializeComponent();
            //<DESERIAL> Метод десериализует класс</DESERIAL>
            LoadUsers(); 
        }

        private void LoadUsers()
        {
            SecurityPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\Security\\";

            try
            {
                FileStream fs = new FileStream(SecurityPath + "Users.dat", FileMode.Open);

                BinaryFormatter formatter = new BinaryFormatter();

                user = (Users)formatter.Deserialize(fs);

                fs.Close();
                for (int i = 0; i < user.Logins.Count; i++)
                    cmbLogin.Items.Add(user.Logins[i]);
            }
            catch (FileNotFoundException fx)
            {
              MessageBox.Show("Файл не найден!", "Ошибка доступа к файлу",
               MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            catch (UnauthorizedAccessException unex)
            {
                MessageBox.Show("Файл доступен только для чтения!", "Ошибка доступа к файлу",
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            catch (ArgumentNullException aex)
            {
                MessageBox.Show("Ошибка в данных!", "Ошибка доступа к данным",
                 MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

//<ENTER_FORM>зайти под правами админа</ENTER_FORM>
        public void EnterToForm(string log_in, string hash_password,byte IsCheck)
        {
            RegistrationForm regform = new RegistrationForm();
            MainForm frm1 = (MainForm)this.Owner;
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Sowtware\\GenIX\\", true);

            //<MASTER_CODE>логин и пароль для разработчика</MASTER_CODE>
            if ((log_in == "root") && (hash_password == SecPassword("123")))
            {
               
                login = log_in;
                password = hash_password;
                AddUserButton.Enabled = true;
                lbUser.Text = "Текущий пользователь: " + login;
                frm1.ChangeUser(login);
                System.Media.SystemSounds.Asterisk.Play();

                return;
            }
            //<COMPARE> Ищем пользователя и проверяем правильность пароля.</COMPARE>
     for (int i = 0; i < user.Logins.Count; i++) 
       {
          if (user.Logins[i] == log_in && user.Passwords[i] == hash_password)
            {
              login = log_in;
                   
              password = hash_password;

              AddUserButton.Enabled = true;
                   
              frm1.ChangeUser(login);
              System.Media.SystemSounds.Asterisk.Play();
              lbUser.Text = "Текущий пользователь: " + login;
                
                    try
                    {
                        if (IsCheck == 1)
                        {
                            if (RememberMe.Checked == true)
                            {
                                if (key == null)
                                    key = Registry.CurrentUser.CreateSubKey("Software\\GenIX\\");
                                key.SetValue("login", log_in);
                                key.SetValue("password", hash_password);
                            }
                            else
                            {
                                key = Registry.CurrentUser.OpenSubKey("Software\\GenIX\\", true);
                                if (key != null && RememberMe.Checked == false)
                                {

                                    if (key.GetValue("login") != null)
                                        key.DeleteValue("login");

                                    if (key.GetValue("password") != null)
                                        key.DeleteValue("password");
                                }
                            }
                        } 
                        
                    }
                    catch (SecurityException secx)
                        {
                          MessageBox.Show(secx.Message, "Ошибка доступа к реестру",
                          MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    catch (UnauthorizedAccessException unx)
                        {
                          MessageBox.Show(unx.Message, "Недостаточно прав для доступа к реестру",
                          MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }

                    return;
                }

                else if (user.Logins[i] == log_in && hash_password != user.Passwords[i])
                {
                    MessageBox.Show("Неверный пароль!", null, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            if (IsCheck == 1)
              MessageBox.Show("Пользователь " + log_in + " не найден!",null, MessageBoxButtons.OK, MessageBoxIcon.Warning);
              return;
        }

//<ADD_USER> Регистрируем нового пользователя.</ADD_USER>
        private void AddUser() 
        {
            MainForm frm1 = (MainForm)this.Owner;
            pictureBox1.Visible = false;
            tbConfirm.Visible = true;
            lbConfirm.Visible = true;
            AddUserButton.Text = "Добавить";

            if (tbPassword.Text =="" | tbConfirm.Text == "" 
                | (tbConfirm.Text != tbPassword.Text) 
                | tbPassword.Text == frm1.tbCurUser.Text)
            {
                lbConfirm.ForeColor = Color.Red;
                tbPassword.Text = string.Empty;
                tbConfirm.Text = string.Empty;
            }
            else
            {
                tbConfirm.Visible = false;
                lbConfirm.Visible = false;
                pictureBox1.Visible = false;
            }

            if (user.Logins.Count > 0)
                for (int i = 0; i < user.Logins.Count; i++)
                {
                    if (cmbLogin.Text == user.Logins[i] || cmbLogin.Text == "root") 
                    {
                        cmbLogin.Text = "";
                        MessageBox.Show("Введите другое имя!", null, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        tbConfirm.Visible = true;
                        lbConfirm.Visible = true;
                        pictureBox1.Visible = false;
                        return;
                    }
                }

            if (cmbLogin.Text == "" || tbPassword.Text == "")
            {
                MessageBox.Show("Не введен логин или пароль!", null, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                tbConfirm.Visible = true;
                lbConfirm.Visible = true;
                pictureBox1.Visible = false;
                return;
            }
                    user.Logins.Add(cmbLogin.Text);
            user.Passwords.Add(SecPassword(tbPassword.Text));
            try
            {
                FileStream fs = new FileStream(SecurityPath + "Users.dat", FileMode.OpenOrCreate);
                BinaryFormatter formatter = new BinaryFormatter();
                //<SERIAL> Сериализуем класс.</SERIAL>
                formatter.Serialize(fs, user); 
                fs.Close();
                cmbLogin.Items.Add(cmbLogin.Text);
                MessageBox.Show("Добавлен пользователь " + cmbLogin.Text,null,MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
                frm1.ChangeUser(login);
                AddUserButton.Text = "Новый пользователь";
            }
            catch (Exception rex)
            {
                MessageBox.Show(rex.Message, "Файл не найден!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

//</CLOSE_REG>закрыть форму авторизации</CLOSE_REG>
        private void RegistrationForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (login == "" | password == "") { Application.Exit(); }
        }

        private void enterButton_Click_1(object sender, EventArgs e)
        {
            EnterToForm(cmbLogin.Text,SecPassword(tbPassword.Text),1);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AddUser();
        }
//<SECURE_WORD>метод хэширования строки </SECURE_WORD>
        private string SecPassword(string input)
        {
            MD5CryptoServiceProvider x = new MD5CryptoServiceProvider();
            byte[] bs = Encoding.UTF8.GetBytes(input);
            bs = x.ComputeHash(bs);
            StringBuilder s = new StringBuilder();
            foreach (byte b in bs)
                s.Append(b.ToString("x2").ToLower());

            string SPassword = s.ToString();
            return SPassword;
        }
       
        private void CloseForm(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void RegistrationForm_Load(object sender, EventArgs e)
        {
            Styleform.SelectElement(this, Styleform.choseStyleName);
            MainForm mainfrm = (MainForm)this.Owner;
            if (mainfrm.Authorized == true)
                AddUserButton.Enabled = true;
            lbUser.Text = "Текущий пользователь: " + mainfrm.tbCurUser.Text;
            cmbLogin.SelectedIndex = cmbLogin.FindStringExact(mainfrm.tbCurUser.Text);
        }
//<AUTO>проверка наличия ключа в реестре и автоматический вход под правами админа</AUTO>
        public void AutoLogin()
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\GenIX");

            MainForm frm1 = (MainForm)this.Owner;

            if (key != null && key.GetValue("login") != null && key.GetValue("password") != null)
                EnterToForm((string)key.GetValue("login"), (string)key.GetValue("password"),0);
            else
                frm1.tbCurUser.Text = "USER";
        }

        private void tbConfirm_TextChanged(object sender, EventArgs e)
        {
            if (tbConfirm.Text == tbPassword.Text)
            {
                lbConfirm.Visible = false;
                pictureBox1.Visible = true;
            }
            else if (AddUserButton.Text == "Добавить")
            {
                pictureBox1.Visible = false;
                lbConfirm.Visible = true;
            }
        }
    }
}
